package com.example.controller.pet;

import com.example.dto.request.group.InsertGroup;
import com.example.dto.request.pet.PersonalPetRequestDTO;
import com.example.dto.request.pet.PersonalPetRequestDTO.ModifyPetProfileGroup;
import com.example.dto.business.PetBriefInfoBusinessDTO;
import com.example.exception.InvalidFileTypeException;
import com.example.pojo.User;
import com.example.response.ErrorStatus;
import com.example.response.ApiResult;
import com.example.dto.business.PetBusinessDTO;
import com.example.service.pet.PersonalPetService;
import com.example.service.user.UserAuthenticationService;
import com.example.util.RequestParamUtil;
import com.example.validator.constraints.FileCount;
import com.example.vo.pet.PersonalPetVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;


/**
 * 实践 REST URL
 *
 * @author Lexin Huang
 */
@Api(tags = "个人宠物模块")
@Validated
@RestController
public class PersonalPetController {

    private final PersonalPetService personalPetService;

    private final UserAuthenticationService authenticationService;

    public PersonalPetController(PersonalPetService personalPetService,
                                UserAuthenticationService authenticationService) {
        this.personalPetService = personalPetService;
        this.authenticationService = authenticationService;
    }

    @GetMapping("/pets/view")
    @ApiOperation("获取用户所有宠物信息")
    @ApiImplicitParam(name = "token", value = "用户令牌", required = true, dataTypeClass = String.class, paramType = "header")
    public ApiResult<PersonalPetVO> getUserPetsBriefInfo(@RequestHeader(value = "token", required = false) String token) {
        User user = authenticationService.login(token);
        List<PetBriefInfoBusinessDTO> pets = personalPetService.getPetsBriefInfo(user.getId());
        ApiResult<PersonalPetVO> response = new ApiResult<>();
        PersonalPetVO vo = new PersonalPetVO();
        vo.setPets(pets);
        response.setSuccess(vo);
        return response;
    }

    @PostMapping("/pets")
    @ApiOperation("添加宠物")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "用户令牌", required = true,
                    dataTypeClass = String.class, paramType = "header")
    })
    public ApiResult<PersonalPetVO> addPet(@RequestHeader("token") String token,
                                           @Validated(value = InsertGroup.class)
                                           @RequestBody PersonalPetRequestDTO requestDTO) {
        PersonalPetVO vo = new PersonalPetVO();
        User user = authenticationService.login(token);
        Integer petId = personalPetService.addPet(user.getId(), requestDTO);
        vo.setPetId(petId);
        ApiResult<PersonalPetVO> result = new ApiResult<>();
        result.setSuccess(vo, "添加宠物成功!");
        return result;
    }


    @PatchMapping("/pets/{petId}/profile")
    @ApiOperation("修改宠物信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "用户令牌", required = true,
                    dataTypeClass = String.class, paramType = "header"),
            @ApiImplicitParam(name = "petId", value = "宠物id", required = true,
                    dataTypeClass = String.class, paramType = "path"),
    })
    public ApiResult<ApiResult.ApiData> modifyPetProfile(@RequestHeader("token") String token,
                                                         @PathVariable(value = "petId") String petIdParam,
                                                         @Validated(ModifyPetProfileGroup.class)
                                                         @RequestBody PersonalPetRequestDTO requestDTO) {
        User user = authenticationService.login(token);
        Integer petId = RequestParamUtil.parseParamAsInteger(petIdParam);
        try {
            personalPetService.modifyPetProfile(user.getId(), petId, requestDTO);
        } catch (DuplicateKeyException e) {
            return ApiResult.buildErrorResponse(ErrorStatus.PET_NAME_NOT_AVAILABLE);
        }
        return ApiResult.buildNonDataSuccessResponse("修改成功!");
    }

    @PatchMapping("/pets/{petId}/avatar")
    @ApiOperation("修改宠物头像")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "用户令牌", required = true,
                    dataTypeClass = String.class, paramType = "header"),
            @ApiImplicitParam(name = "petId", value = "宠物id", required = true,
                    dataTypeClass = String.class, paramType = "path"),
            @ApiImplicitParam(name = "image", value = "图片文件", required = true,
                    dataTypeClass = MultipartFile.class, paramType = "form")
    })
    public ApiResult<PersonalPetVO> uploadAvatar(@RequestHeader(value = "token") String token,
                                                     @PathVariable("petId") String petIdParam,
                                                     @FileCount(min = 1) @RequestParam("image") MultipartFile[] images) {
        User user = authenticationService.login(token);
        Integer petId = RequestParamUtil.parseParamAsInteger(petIdParam);

        ApiResult<PersonalPetVO> response = new ApiResult<>();
        try {
            String avatarUrl = personalPetService.replaceAvatar(petId, user.getId(), images[0]);
            PersonalPetVO vo = new PersonalPetVO();
            vo.setPetPortraitPath(avatarUrl);
            response.setSuccess(vo);
        } catch (InvalidFileTypeException e) {
            response.setError(ErrorStatus.INVALID_IMAGE_FILE, e.getMessage());
        }
        return response;
    }

    @PostMapping("/pets/{petId}/photos")
    @ApiOperation("上传指定宠物的相册图片")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "用户令牌", required = true,
                    dataTypeClass = String.class, paramType = "header"),
            @ApiImplicitParam(name = "photo", value = "宠物照片", required = true,
                    dataTypeClass = MultipartFile.class, paramType = "form")
    })
    public ApiResult<ApiResult.ApiData> uploadPetPhoto(@RequestHeader(name = "token") String token,
                                                       @PathVariable(name = "petId") String petIdParam,
                                                       @FileCount(max = 5, message = "单次最多上传5张图片!")
                                                       @RequestParam(name = "photos") MultipartFile[] photos) {
        User user = authenticationService.login(token);
        Integer petId = RequestParamUtil.parseParamAsInteger(petIdParam);
        try {
            personalPetService.addPetPhotos(user.getId(), petId, photos);
        } catch (IOException e) {
            return ApiResult.buildErrorResponse(ErrorStatus.PET_PHOTO_SERVICE_NOT_AVAILABLE);
        }
        return ApiResult.buildNonDataSuccessResponse("上传图片成功!");
    }

    @DeleteMapping("/pets/{petId}")
    @ApiOperation("删除指定宠物")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "用户令牌", required = true,
                    dataTypeClass = String.class, paramType = "header"),
            @ApiImplicitParam(name = "petId", value = "宠物id", required = true,
                    dataTypeClass = String.class, paramType = "path")
    })
    public ApiResult<ApiResult.ApiData> removePet(@RequestHeader(value = "token") String token,
                                                  @PathVariable("petId") String petIdParam) {
        User user = authenticationService.login(token);
        Integer petId = RequestParamUtil.parseParamAsInteger(petIdParam);
        personalPetService.removeById(user.getId(), petId);
        return ApiResult.buildNonDataSuccessResponse("删除宠物成功!");

    }


    @GetMapping("/pets/{petId}/collar_ip")
    @ApiOperation("获取对应宠物的绑定项圈的id")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "用户令牌", required = true,
                    dataTypeClass = String.class, paramType = "header"),
            @ApiImplicitParam(name = "petId", value = "宠物id", required = true,
                    dataTypeClass = String.class, paramType = "path")
    })
    public ApiResult<PersonalPetVO> getPetCollarIp(@RequestHeader(value = "token", required = false) String token,
                                                     @PathVariable("petId") String petIdParam) {
        Integer petId = RequestParamUtil.parseParamAsInteger(petIdParam);
        User user = authenticationService.login(token);
        String collarIp = personalPetService.getPetCollarIp(user.getId(), petId);
        ApiResult<PersonalPetVO> response = new ApiResult<>();
        PersonalPetVO vo = new PersonalPetVO();
        vo.setCollarIp(collarIp);
        response.setSuccess(vo);
        return response;
    }

    @GetMapping("/pets/{petId}")
    @ApiOperation("获取指定id的宠物详细信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "用户令牌", required = true,
                    dataTypeClass = String.class, paramType = "header"),
            @ApiImplicitParam(name = "petId", value = "宠物id", required = true,
                    dataTypeClass = String.class, paramType = "path")
    })
    public ApiResult<PersonalPetVO> getPersonalPetDetailedInfo(@RequestHeader(value = "token") String token,
                                                               @PathVariable("petId") String petIdParam) {
        User user = authenticationService.login(token);
        Integer petId = RequestParamUtil.parseParamAsInteger(petIdParam);

        PetBusinessDTO pet = personalPetService.getPetDetailedInfo(user.getId(), petId);
        ApiResult<PersonalPetVO> result = new ApiResult<>();
        PersonalPetVO data = new PersonalPetVO();
        data.setPet(pet);
        result.setSuccess(data);
        return result;
    }

}
